package common

import (
	"alertmanagerWebhook/config"
	"alertmanagerWebhook/core"
	"alertmanagerWebhook/global"
	"bytes"

	"os"
	"path/filepath"
	"reflect"
	"text/template"
	"time"

	"github.com/gomodule/redigo/redis"
)

func TransformToMarkdown(notification config.Notification) (message *config.Message, err error) {
	c, err := core.ConnRedis()
	if err != nil {
		global.Logger.Errorf("Failed to connect to Redis: %v\n", err)
		return
	}
	defer c.Close() // 确保在函数结束时关闭连接

	var (
		notificationFiring   config.Notification
		notificationResolved config.Notification

		cstZone = time.FixedZone("CST", 8*3600)

		bufferFiring   bytes.Buffer
		bufferResolved bytes.Buffer
	)
	dir, err := os.Getwd()
	if err != nil {
		global.Logger.Errorf("Error getting current directory: %v\n", err)
		return
	}
	// Use filepath.Join to create the correct file path
	templatePath := filepath.Join(dir, "/template/alert.tmpl")
	for _, alert := range notification.Alerts {
		if alert.Status == "firing" {
			notificationFiring.Version = notification.Version
			notificationFiring.GroupKey = notification.GroupKey
			notificationFiring.Status = "firing"
			notificationFiring.Receiver = notification.Receiver
			notificationFiring.GroupLabels = notification.GroupLabels
			notificationFiring.CommonLabels = notification.CommonLabels
			notificationFiring.ExternalURL = notification.ExternalURL
			notificationFiring.Alerts = append(notificationFiring.Alerts, alert)
		} else if alert.Status == "resolved" {
			notificationResolved.Version = notification.Version
			notificationResolved.GroupKey = notification.GroupKey
			notificationResolved.Status = "resolved"
			notificationResolved.Receiver = notification.Receiver
			notificationResolved.GroupLabels = notification.GroupLabels
			notificationResolved.CommonLabels = notification.CommonLabels
			notificationResolved.ExternalURL = notification.ExternalURL
			notificationResolved.Alerts = append(notificationResolved.Alerts, alert)
		}
	}

	// Templated Email Body for Firing Alerts
	if !reflect.DeepEqual(notificationFiring, config.Notification{}) {
		for _, alert := range notificationFiring.Alerts {
			alert.StartTime = alert.StartsAt.In(cstZone).Format("2006-01-02 15:04:05")
			fingerprint := alert.Fingerprint

			// Save states in Redis  -->hset fingerprintValue startTimeValue存储，key的名称就是fingerprintValue，字段就是startTime
			if _, err = c.Do("HSet", fingerprint, "startTime", alert.StartTime); err != nil {
				global.Logger.Errorln(err)
				return nil, err
			}
			//Redis Hincrby 命令用于为哈希表中的递增字段值加上指定增量值
			if _, err = c.Do("Hincrby", fingerprint, "count", 1); err != nil {
				global.Logger.Errorln(err)
				return nil, err
			}

			count, err := redis.Int(c.Do("HGet", fingerprint, "count"))
			if err != nil {
				global.Logger.Errorln("get alert count error: ", err)
			}
			alert.Count = count

			// 检查 Description 是否存在或为空
			if alert.Annotations.Description == "" {
				// 如果为空，则重新赋值
				alert.Annotations.Description = alert.Annotations.Summary
			}
			//告警级别如果为空，则设置为warning
			if alert.Labels.Severity == "" {
				alert.Labels.Severity = "warning"
			}
			// Load template from file
			tmpl, err := template.ParseFiles(templatePath)
			if err != nil {
				global.Logger.Errorln("template parse error: ", err)
				return nil, err
			}
			// Execute the template and write to emailBodyFiring
			if err := tmpl.Execute(&bufferFiring, alert); err != nil {
				global.Logger.Errorln("template execute error: ", err)
				return nil, err
			}
			bufferFiring.WriteString("\n") // 添加换行符以分隔不同的告警
		}
	}

	// Templated Email Body for Resolved Alerts
	if !reflect.DeepEqual(notificationResolved, config.Notification{}) {
		for _, alert := range notificationResolved.Alerts {
			alert.StartTime = alert.StartsAt.In(cstZone).Format("2006-01-02 15:04:05")
			alert.EndTime = alert.EndsAt.In(cstZone).Format("2006-01-02 15:04:05")
			// 检查 Description 是否存在或为空
			if alert.Annotations.Description == "" {
				// 如果为空，则重新赋值
				alert.Annotations.Description = alert.Annotations.Summary
			}
			// Load template from file
			tmpl, err := template.ParseFiles(templatePath)
			if err != nil {
				global.Logger.Errorln("template parse error: ", err)
				return nil, err
			}
			// Execute the template and write to emailBodyResolved
			if err := tmpl.Execute(&bufferResolved, alert); err != nil {
				global.Logger.Errorln("template execute error: ", err)
				return nil, err
			}
			bufferResolved.WriteString("\n") // 添加换行符以分隔不同的告警

			//恢复后，从redis删除对应的key
			if _, err := c.Do("Del", alert.Fingerprint); err != nil {
				global.Logger.Errorln("delete key error: ", err)
			}
		}
	}

	// 转换为企业微信可以识别的格式
	var markdownFiring, markdownResolved *config.QyWeChatMarkdown
	var title string
	title = "# <font color=\"red\">触发告警</font>\n"
	if bufferFiring.String() != "" {
		markdownFiring = config.NewQyWeChatMarkdown(title + bufferFiring.String())
	} else {
		markdownFiring = config.NewQyWeChatMarkdown("")
	}
	title = "# <font color=\"green\">告警恢复</font>\n"
	if bufferResolved.String() != "" {
		markdownResolved = config.NewQyWeChatMarkdown(title + bufferResolved.String())
	} else {
		markdownResolved = config.NewQyWeChatMarkdown("")
	}

	// 转换为钉钉可以识别的格式
	var dmarkdownFiring, dmarkdownResolved *config.DingDingMarkdown
	title = "# <font color=\"#FF0000\">触发告警</font>\n\n"
	if bufferFiring.String() != "" {
		dmarkdownFiring = config.NewDingDingMarkdown("触发告警", title+bufferFiring.String())
	} else {
		dmarkdownFiring = config.NewDingDingMarkdown("", "")
	}

	title = "# <font color=\"#008000\">告警恢复</font>\n\n"
	if bufferResolved.String() != "" {
		dmarkdownResolved = config.NewDingDingMarkdown("告警恢复", title+bufferResolved.String())
	} else {
		dmarkdownResolved = config.NewDingDingMarkdown("", "")
	}

	// 将企业微信、飞书、钉钉消息进行封装
	message = config.NewMessage(markdownFiring, markdownResolved, dmarkdownFiring, dmarkdownResolved)
	//log.Printf("messages: %v\n", message.QywechatMessage.MarkdownFiring.Markdown.Content)
	// 仅在 DingDing 启用的情况下记录其信息
	if global.Config.DingDing.Enabled {
		global.Logger.Infof("messagesDDFiring: %v\n", message.DingdingMessage.DmarkdownFiring.Dmarkdown.Text)
		global.Logger.Infof("messagesDDResovled: %v\n", message.DingdingMessage.DmarkdownResolved.Dmarkdown.Text)
	}
	global.Logger.Infof("messagesWeChatFiring: %v\n", message.QywechatMessage.MarkdownFiring.Markdown.Content)
	global.Logger.Infof("messagesWeChatResovled: %v\n", message.QywechatMessage.MarkdownResolved.Markdown.Content)
	return message, nil
}
